package xstring

import (
	"strconv"
	"strings"
)

// 字符串转uint
//
//	s	string	待转换的字符串
func ToUint(s string) uint {
	return uint(ToInt(s))
}

// 字符串转uint8
//
//	s	string	待转换的字符串
func ToUint8(s string) uint8 {
	return uint8(ToInt(s))
}

// 字符串转uint16
//
//	s	string	待转换的字符串
func ToUint16(s string) uint16 {
	return uint16(ToInt(s))
}

// 字符串转int8类型
//
//	s	string	待转换的字符串
func ToInt8(s string) int8 {
	return int8(ToInt(s))
}

// 字符串转int16类型
//
//	s	string	待转换的字符串
func ToInt16(s string) int16 {
	return int16(ToInt(s))
}

// 字符串转int32类型
//
//	s	string	待转换的字符串
func ToInt32(s string) int32 {
	return int32(ToInt(s))
}

// 字符串转int32类型
//
//	s	string	待转换的字符串
func ToUint32(s string) uint32 {
	return uint32(ToInt(s))
}

// 字符串转int
//
//	s	string	待转换的字符串
func ToInt(s string) int {
	s = stringreps(s)
	if s, err := strconv.Atoi(s); err == nil {
		return s
	}
	return 0
}

// 字符串转int64
//
//	s	string	待转换的字符串
func ToInt64(s string) int64 {
	s = stringreps(s)
	if ss, err := strconv.ParseInt(s, 10, 64); err == nil {
		return ss
	} else if a, err := strconv.ParseFloat(s, 64); err == nil {
		return int64(a)
	}
	return 0
}

// 字符串转uint64
//
//	s	string	待转换的字符串
func ToUint64(s string) uint64 {
	s = stringreps(s)
	if ss, err := strconv.ParseUint(s, 10, 64); err == nil {
		return ss
	}
	return 0
}

// 字符串转float32
//
//	s	string	待转换的字符串
func ToFloat32(s string) float32 {
	return float32(ToFloat64(s))
}

// 字符串转float64
//
//	s	string	待转换的字符串
func ToFloat64(s string) float64 {
	s = stringreps(s)
	if s, err := strconv.ParseFloat(s, 64); err == nil {
		return s
	}
	return 0
}

// 二进制转十进制
//
//	s	string	需要转换的二进制数
func B2Int(s string) (num int64) {
	l := len(s)
	for i := l - 1; i >= 0; i-- {
		num += (int64(s[l-i-1]) & 0xf) << uint(i)
	}
	// 开始循环
	// 传入数据：11010
	// 因为是使用了i--的形式，所以实际使用为倒叙方法
	// 第5轮，l=5，i=4，num=0，int64(s[l-i-1])&0xf=1，(int64(s[l-i-1])&0xf)<<uint8(i)=16,num(2)：0
	// 第4轮，l=5，i=3，num=16，int64(s[l-i-1])&0xf=1，(int64(s[l-i-1])&0xf)<<uint8(i)=8,num(2)：10000
	// 第3轮，l=5，i=2，num=24，int64(s[l-i-1])&0xf=0，(int64(s[l-i-1])&0xf)<<uint8(i)=0,num(2)：11000
	// 第2轮，l=5，i=1，num=24，int64(s[l-i-1])&0xf=1，(int64(s[l-i-1])&0xf)<<uint8(i)=2,num(2)：11000
	// 第1轮，l=5，i=0，num=26，int64(s[l-i-1])&0xf=0，(int64(s[l-i-1])&0xf)<<uint8(i)=0,num(2)：11010
	// 备注
	// int64(s[l-i-1]) 是为了将字符串的数字转换为整数，并且格式化成int64类型（方便计算）
	//     将上一步的结果与0xf进行按位与计算，获得真实数据0/1
	//     使用<<将获得的结果向左位移，按照规则右侧自动补0，所以获得二进制的10000
	//         同理，将下一位数据进行计算，并与上一步进行相加，获得：11000
	return
}

// 字符串替换
// 将数字提取出来
//
//	s	待替换的字符串
func stringreps(s string) string {
	s = strings.ReplaceAll(s, ",", "")
	s = strings.ReplaceAll(s, "\n", "")
	s = strings.TrimSpace(s)
	return s
}

// 16进制转二进制byte
//
//	str	待转换的16进制字符串
func Hex2Bin(str string) []byte {
	slen := len(str)
	bHex := make([]byte, len(str)/2)
	ii := 0
	for i := 0; i < len(str); i = i + 2 {
		if slen != 1 {
			ss := string(str[i]) + string(str[i+1])
			bt, _ := strconv.ParseInt(ss, 16, 32)
			bHex[ii] = byte(bt)
			ii = ii + 1
			slen = slen - 2
		}
	}
	return bHex
}
